package com.partner.sys.attach.listener;

import com.alibaba.fastjson.JSONObject;
import com.partner.common.core.dto.IViewObject;
import com.partner.common.core.dto.MechanismDTO;
import com.partner.common.core.event.AbstractEntityEvent;
import com.partner.common.core.service.AbstractMetaEntityListener;
import com.partner.common.core.util.EntityUtil;
import com.partner.common.exception.ParamsNotValidException;
import com.partner.framework.meta.MetaDataEntity;
import com.partner.sys.attach.api.SysAttachMainApi;
import com.partner.sys.attach.constant.AttachBindTypeEnum;
import com.partner.sys.attach.constant.AttachConstant;
import com.partner.sys.attach.dto.SysAttachBindVO;
import com.partner.common.dto.partner.SysAttachMainVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;


/**
 * 附件机制监听服务
 *
 * @author qugp
 * 2019年3月26日
 */
@Slf4j
@Component
public class SysAttachMetaEntityListener extends AbstractMetaEntityListener<AbstractEntityEvent> {

    @Autowired(required = false)
    private SysAttachMainApi sysAttachMainApi;


    /**
     * 是否支持
     */
    @Override
    public boolean support(MetaDataEntity metaEntity) {
        return getFeature(metaEntity, SysAttachMainVO.class.getName()) != null;
    }


    /**
     * 提供附件在机制数据中的key
     */
    @Override
    public String getMechanismKey() {
        return AttachConstant.moduleName;
    }

    @Override
    public String getModuleName() {
        return AttachConstant.moduleName;
    }

    /**
     * 保存主文档之前，校验附件机制数据合法性
     */
    @Override
    public void checkAdd(MetaDataEntity metaEntity, IViewObject data) {
        super.checkAdd(metaEntity, data);


    }

    /**
     * 新增主文档时，执行附件绑定
     */
    @Override
    public void doAdd(MetaDataEntity metaEntity, IViewObject data) {
        super.doAdd(metaEntity, data);
        this.bindAttach(metaEntity, data, true);
    }

    /**
     * 更新主文档之前，校验附件机制数据合法性
     */
    @Override
    public void checkUpdate(MetaDataEntity metaEntity, IViewObject data) {
        super.checkUpdate(metaEntity, data);

    }


    /**
     * 更新主文档时，执行附件绑定
     */
    @Override
    public void doUpdate(MetaDataEntity metaEntity, IViewObject data) {
        super.doUpdate(metaEntity, data);

        if (data.getMechanisms() == null) {
            return;
        }
        if (!data.getMechanisms().containsKey(AttachConstant.moduleName)) {
            return;
        }

        String jsonString = JSONObject.toJSONString(data.getMechanisms().get(AttachConstant.moduleName));
        List<SysAttachMainVO> bindList = JSONObject.parseArray(jsonString, SysAttachMainVO.class);
        if (CollectionUtils.isEmpty(bindList)) {
            return;
        }
        for (SysAttachMainVO sysAttachMainVO : bindList) {
            String fdBindType = sysAttachMainVO.getFdBindType();
            switch (fdBindType) {
                case "ADD":
                    doAdd(metaEntity, data);
                    break;
                case "DELETE":
                    doDelete(metaEntity, data);
                    break;
            }
        }
    }

    /**
     * 绑定附件
     */
    private void bindAttach(MetaDataEntity metaEntity, IViewObject data, boolean isAdd) {
        if (data.getMechanisms() == null) {
            return;
        }
        if (!data.getMechanisms().containsKey(AttachConstant.moduleName)) {
            return;
        }

        String jsonString = JSONObject.toJSONString(data.getMechanisms().get(AttachConstant.moduleName));
        List<SysAttachMainVO> bindList = JSONObject.parseArray(jsonString, SysAttachMainVO.class);
        if (CollectionUtils.isEmpty(bindList)) {
            return;
        }
        SysAttachBindVO bindVO = new SysAttachBindVO();
        bindVO.setFdEntityId(data.getFdId());
        bindVO.setFdEntityName(metaEntity.getEntityName());
        bindAttachFiles(bindList, bindVO, isAdd);
    }

    /**
     * 对附件列表进行绑定
     *
     * @param bindList 附件列表
     * @param bindVO   绑定的附件vo
     */
    public void bindAttachFiles(List<SysAttachMainVO> bindList, SysAttachBindVO bindVO, boolean isAdd) {
        List<SysAttachMainVO> addedAttachFiles = new ArrayList<>();
        List<SysAttachMainVO> deletedAttachFiles = new ArrayList<>();
        List<SysAttachMainVO> editedAttachFiles = new ArrayList<>();
        for (SysAttachMainVO attachFileData : bindList) {
            if (isAdd && StringUtils.isEmpty(attachFileData.getFdBindType())) {
                // 新增场景，且没有fdBindType的附件，默认做新增附件处理
                attachFileData.setFdBindType(AttachBindTypeEnum.ADD.getValue());
            } else if (StringUtils.isEmpty(attachFileData.getFdBindType())) {
                // 非新增场景，且没有fdBindType的附件，说明没有发生变化，不做处理
                continue;
            }

            if (AttachBindTypeEnum.ADD.getValue().equals(attachFileData.getFdBindType())) {
                //新增检查逻辑如果附件Id已经存在绑定关系，则拷贝一份新文件，跟主文档进行绑定
                addedAttachFiles.add(attachFileData);
            } else if (AttachBindTypeEnum.DELETE.getValue().equals(attachFileData.getFdBindType())) {
                deletedAttachFiles.add(attachFileData);
            } else if (AttachBindTypeEnum.EDIT.getValue().equals(attachFileData.getFdBindType())) {
                editedAttachFiles.add(attachFileData);
            } else {
                throw new ParamsNotValidException("未识别的bindType" );
            }
        }
        bindVO.setAddedAttachFiles(addedAttachFiles);
        bindVO.setDeletedAttachFiles(deletedAttachFiles);
        bindVO.setEditedAttachFiles(editedAttachFiles);
        // 调用绑定接口
        sysAttachMainApi.bind(bindVO);
    }


    @Override
    public void doDelete(MetaDataEntity metaEntity, IViewObject data) {
        super.doDelete(metaEntity, data);

        MechanismDTO entityVO = MechanismDTO.of(metaEntity.getEntityName(), data.getFdId());

         sysAttachMainApi.deleteByEntity(entityVO);
    }

    @Override
    public void doLoad(MetaDataEntity metaEntity, IViewObject data) {
        // 加载附件列表
        List<SysAttachMainVO> list = sysAttachMainApi.listByEntity(MechanismDTO.of(metaEntity.getEntityName(), data.getFdId()));
        EntityUtil.appendMechanism(data, AttachConstant.moduleName, list);
    }


}